﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using TimeTrak.BLL;

namespace TimeTrak
{
    public partial class MainForm : Form
    {
        TimeTrakController controller;
        Timer uiUpdateTimer;

        int trackCheckBoxIndex;
        int doneCheckBoxIndex;
        int idIndex;
        int descriptionIndex;

        private TimeTrak.Properties.Settings Settings
        {
            get { return TimeTrak.Properties.Settings.Default; }
        }

        public MainForm()
        {
            InitializeComponent();

            try
            {

                uiUpdateTimer = new Timer();
                uiUpdateTimer.Interval = 3000;
                uiUpdateTimer.Tick += new EventHandler(uiUpdateTimer_Tick);

                trackCheckBoxIndex = dataGridView1.Columns["Tracking"].Index;
                doneCheckBoxIndex = dataGridView1.Columns["Done"].Index;
                idIndex = dataGridView1.Columns["ID"].Index;
                descriptionIndex = dataGridView1.Columns["Description"].Index;

                dataGridView1.AutoGenerateColumns = false;

                controller = new TimeTrakController();

                string path = Settings.CurrentPathSetting;
                if (path.Length > 0)
                {
                    LoadDataFile(path);
                }

            }
            catch (Exception ex)
            {
                HandleException(new Exception("Error initializing MainForm!", ex));
            }
        }


        private void UpdateDataGridView()
        {
            try
            {

                Console.Out.WriteLine("Updating UI!");
                controller.UpdateTaskTimes();
                HoursTodayLabel.Text = controller.GetHoursForDate(DateTime.Today).TotalHours.ToString("N2");
                HoursWeekLabel.Text = controller.GetHoursWTD(DateTime.Today).TotalHours.ToString("N2");
                dataGridView1.Invalidate();
                dataGridView1.Update();
            }
            catch (Exception ex)
            {
                throw new Exception("Error Updating UI!", ex);
            }

        }

        private DataGridViewRow GetRowFromIndex(int rowIndex)
        {
            try
            {
                DataGridViewRow row = null;
                if (rowIndex > -1)
                {
                    row = dataGridView1.Rows[rowIndex];
                }
                return row;
            }
            catch (Exception ex)
            {
                throw new Exception("Error getting row from index!", ex);
            }
        }


        private int GetTaskIDFromRow(DataGridViewRow row)
        {
            try
            {
                return (int)row.Cells[idIndex].Value;
            }
            catch (Exception ex)
            {
                throw new Exception("Error getting task ID from row!", ex);
            }
        }


        private void SetDone(int rowIndex, int taskID, bool value)
        {
            try
            {
                if (value == true)
                {
                    //stop tracking if its done
                    SetTracking(taskID, false);

                    //disable tracking checkbox (everything else?)
                    dataGridView1.Rows[rowIndex].Cells[trackCheckBoxIndex].ReadOnly = true;

                    //strikethough description box
                    Font f1 = dataGridView1.Font;
                    Font f2 = new Font(f1, FontStyle.Strikeout);
                    dataGridView1.Rows[rowIndex].Cells[descriptionIndex].Style.Font = f2;

                }
                else
                {
                    //enable tracking checkbox (everything else?)
                    dataGridView1.Rows[rowIndex].Cells[trackCheckBoxIndex].ReadOnly = false;


                    //unstrikethrough the description box
                    Font f1 = dataGridView1.Font;
                    Font f2 = new Font(f1, FontStyle.Regular);
                    dataGridView1.Rows[rowIndex].Cells[descriptionIndex].Style.Font = f2;
                }

            }
            catch (Exception ex)
            {
                throw new Exception("Error Seting Done!", ex);
            }
        }

        private void SetTracking(int taskID, bool value)
        {
            try
            {
                controller.SetTracking(taskID, value);
            }
            catch (Exception ex)
            {
                throw new Exception("Error Seting Tracking!", ex);
            }
        }


        private void LoadDataFile(string filePath)
        {
            try
            {
                controller.LoadDataFile(filePath);
                dataGridView1.DataSource = controller.TaskList;

                UpdateDataGridView();
                uiUpdateTimer.Start();

                Settings.CurrentPathSetting = filePath;
                Settings.Save();
            }
            catch (Exception ex)
            {
                throw new Exception("Error loading data file!", ex);
            }
        }

        #region Event Handlers

        void uiUpdateTimer_Tick(object sender, EventArgs e)
        {
            try
            {
                UpdateDataGridView();
            }
            catch (Exception ex)
            {
                HandleException(new Exception("Error in uiUpdateTimer_Tick!", ex));
            }
        }


        private void dataGridView1_CellContentClick(object sender, DataGridViewCellEventArgs e)
        {
            try
            {

                //Console.Out.WriteLine("dataGridView1_CellContentClick()");
                if (e.RowIndex > -1)
                {
                    DataGridViewRow row = GetRowFromIndex(e.RowIndex);
                    int id = GetTaskIDFromRow(row);
                    if (e.ColumnIndex == trackCheckBoxIndex)
                    {
                        dataGridView1.EndEdit();
                        bool value = (bool)row.Cells[e.ColumnIndex].Value;
                        SetTracking(id, value);
                        UpdateDataGridView();
                    }
                    else if (e.ColumnIndex == doneCheckBoxIndex)
                    {
                        dataGridView1.EndEdit();
                        bool value = (bool)row.Cells[e.ColumnIndex].Value;
                        SetDone(e.RowIndex, id, value);
                        UpdateDataGridView();


                    }
                }
            }
            catch (Exception ex)
            {
                HandleException(new Exception("Error in dataGridView1_CellContentClick!", ex));
            }
        }


        //handle the second click of a double click as a regular single click
        private void dataGridView1_CellContentDoubleClick(object sender, DataGridViewCellEventArgs e)
        {
            try
            {
                dataGridView1_CellContentClick(sender, e);
            }
            catch (Exception ex)
            {
                HandleException(new Exception("Error in dataGridView1_CellContentDoubleClick!", ex));
            }
        }



        private void AddTaskButton_Click(object sender, EventArgs e)
        {
            try
            {
                controller.AddNewTask();
                UpdateDataGridView();
            }
            catch (Exception ex)
            {
                HandleException(new Exception("Error in AddTaskButton_Click!", ex));
            }
        }
        private void addNewTaskToolStripMenuItem_Click(object sender, EventArgs e)
        {
            try
            {
                controller.AddNewTask();
                UpdateDataGridView();
            }
            catch (Exception ex)
            {
                HandleException(new Exception("Error in addNewTaskToolStripMenuItem_Click!", ex));
            }
        }
        private void AddStripButton_Click(object sender, EventArgs e)
        {
            try
            {
                controller.AddNewTask();
                UpdateDataGridView();
            }
            catch (Exception ex)
            {
                HandleException(new Exception("Error in AddStripButton_Click!", ex));
            }
        }



        private void dataGridView1_CellEndEdit(object sender, DataGridViewCellEventArgs e)
        {
            try
            {
                if (e.ColumnIndex != trackCheckBoxIndex)
                {
                    controller.SaveData();
                }
            }
            catch (Exception ex)
            {
                HandleException(new Exception("Error in dataGridView1_CellEndEdit!", ex));
            }
        }

        private void MainForm_FormClosed(object sender, FormClosedEventArgs e)
        {
            try
            {
                controller.SaveData();
            }
            catch (Exception ex)
            {
                HandleException(new Exception("Error in MainForm_FormClosed!", ex));
            }
        }

        private void toggleTrackingToolStripMenuItem_Click(object sender, EventArgs e)
        {
            try
            {
                int rowIndex = dataGridView1.SelectedRows[0].Index;
                DataGridViewRow row = GetRowFromIndex(rowIndex);
                bool currentCheckedValue = (bool)row.Cells[trackCheckBoxIndex].Value;
                int id = GetTaskIDFromRow(row);

                SetTracking(id, !currentCheckedValue);
                UpdateDataGridView();
            }
            catch (Exception ex)
            {
                HandleException(new Exception("Error in toggleTrackingToolStripMenuItem_Click!", ex));
            }
        }

        private void deleteToolStripMenuItem_Click(object sender, EventArgs e)
        {
            try
            {
                int rowIndex = dataGridView1.SelectedRows[0].Index;
                DataGridViewRow row = GetRowFromIndex(rowIndex);
                int id = GetTaskIDFromRow(row);
                Task item = controller.GetTask(id);


                string msg = String.Format("Are you sure you want to delete the '{0}' task?", item.Description);
                if (MessageBox.Show(msg, "Delete Task", MessageBoxButtons.YesNo) == DialogResult.Yes)
                {
                    controller.DeleteTask(id);
                }
            }
            catch (Exception ex)
            {
                HandleException(new Exception("Error in deleteToolStripMenuItem_Click!", ex));
            }

        }

        private void dataGridView1_CellMouseDown(object sender, DataGridViewCellMouseEventArgs e)
        {
            try
            {
                //Console.Out.WriteLine("CellMouseDown!");
                if (e.Button == MouseButtons.Right)
                {
                    if (e.RowIndex > -1)
                    {
                        dataGridView1.Rows[e.RowIndex].Selected = true;
                    }
                }
            }
            catch (Exception ex)
            {
                HandleException(new Exception("Error in dataGridView1_CellMouseDown!", ex));
            }
        }

        private void MainForm_Resize(object sender, EventArgs e)
        {
            try
            {
                if (FormWindowState.Minimized == WindowState)
                {
                    notifyIcon1.Visible = true;
                    Hide();
                }
            }
            catch (Exception ex)
            {
                HandleException(new Exception("Error in MainForm_Resize!", ex));
            }

        }


        private void notifyIcon1_Click(object sender, EventArgs e)
        {
            try
            {
                notifyIcon1.Visible = false;
                Show();
                this.WindowState = FormWindowState.Normal;
            }
            catch (Exception ex)
            {
                HandleException(new Exception("Error in notifyIcon1_Click!", ex));
            }

        }

        private void openToolStripMenuItem_Click(object sender, EventArgs e)
        {
            try
            {
                if (openFileDialog1.ShowDialog() == DialogResult.OK)
                {
                    string filePath = openFileDialog1.FileName;
                    LoadDataFile(filePath);
                }
            }
            catch (Exception ex)
            {
                HandleException(new Exception("Error in openToolStripMenuItem_Click!", ex));
            }

        }


        private void newToolStripMenuItem_Click(object sender, EventArgs e)
        {
            try
            {
                if (saveFileDialog1.ShowDialog() == DialogResult.OK)
                {
                    string filePath = saveFileDialog1.FileName;
                    controller.CreateNewDataFile(filePath);
                    LoadDataFile(filePath);
                }
            }
            catch (Exception ex)
            {
                HandleException(new Exception("Error in newToolStripMenuItem_Click!", ex));
            }
        }

        #endregion

        private void HandleException(Exception ex)
        {
            string msg = "Oh Noes! Error!\n";
            Exception ex2 = ex;
            msg += ex2.Message + "\n";
            ex2 = ex2.InnerException;
            while (ex2 != null)
            {
                msg += ex2.Message + "\n";
                ex2 = ex2.InnerException;
            }
            MessageBox.Show(msg);
        }






    }
}
